/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.academik.controller;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import org.academik.model.Anioescolar;
import org.academik.model.Grado;
import org.academik.model.Nivel;
import org.academik.model.Seccion;
import org.academik.util.FacesUtil;
import org.academik.util.HibernateUtil;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author Javier
 */
@ManagedBean(name = "seccionBean")
@ViewScoped
public class SeccionBean extends AbstractViewScopedBean implements Serializable {

    /** Declaracion de Variables */
    private Seccion seccion;
    private Long selectedAnio;
    private Long selectedNivel;
    private Long selectedGrado;
    private ArrayList<SelectItem> listaGrados;
    private ArrayList secciones;
    private Object[] selectedSeccion;
    private String url;
    private String selectedListado;
    private String selectedTipoArchivo;

    /** Creates a new instance of SeccionBean */
    public SeccionBean() {
        this.nuevo();
    }

    @Override
    public void crear() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        try {
            tx = (Transaction) session.beginTransaction();
            Grado tempGrado = (Grado) session.load(Grado.class, this.selectedGrado);
            Anioescolar tempAnio =   (Anioescolar) session.load(Anioescolar.class, this.selectedAnio);
            this.seccion.setGrado(tempGrado);
            this.seccion.setAnioescolar(tempAnio);
            session.saveOrUpdate(this.seccion);
            session.flush();
            session.clear();
            tx.commit();
            this.nuevo();
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_INFO, "Información:", "La sección se creo satisfactoriamente"));
        } catch (HibernateException e) {
            tx.rollback();
            FacesUtil.hibernateException(e);
        } finally {
            session.close();
        }
    }

    @Override
    public void eliminar() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        Seccion tempSeccion = (Seccion) this.selectedSeccion[0];
        Seccion s = (Seccion) session.load(Seccion.class, tempSeccion.getIdSeccion());
        try {
            tx = (Transaction) session.beginTransaction();
            session.delete(s);
            session.flush();
            session.clear();
            tx.commit();
            this.nuevo();
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Información:", "Registro eliminado satisfactoriamente"));
        } catch (HibernateException e) {
            tx.rollback();
            FacesUtil.hibernateException(e);
        } finally {
            session.close();
        }
    }

    @Override
    public void cargarOpciones() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void cargarOpciones(int id) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void buscar() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void modificar() {
        this.seccion = new Seccion();
        Grado tempGrado = (Grado) this.selectedSeccion[1];
        Seccion tempSeccion = (Seccion) this.selectedSeccion[0];
        Anioescolar tempAnio = (Anioescolar) this.selectedSeccion[3];
        this.selectedGrado = tempGrado.getIdGrado();
        this.selectedAnio = tempAnio.getIdAnioEscolar();

        Session session = HibernateUtil.getSessionFactory().openSession();
        Grado g = (Grado) session.load(Grado.class, this.selectedGrado);
        this.selectedNivel = g.getNivel().getIdNivel();

        this.onSelectNivel();
        this.seccion = tempSeccion;
        session.close();
    }

    @Override
    public void cargarResgistros() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void nuevo() {
        this.seccion = new Seccion();
        this.selectedAnio = null;
        this.selectedNivel = null;
        this.selectedGrado = null;
        this.selectedSeccion = null;
        this.listaGrados = new ArrayList<SelectItem>();
        this.secciones = new ArrayList();
        this.url = null;
        this.selectedListado = null;
        this.selectedSeccion = null;
        this.selectedTipoArchivo = null;
        this.populateSecciones();
    }

    public void imprimir() {
        if (this.selectedSeccion != null) {
            String contextPath = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
            this.url = contextPath + "/faces/createReportServlet?fileName=";
            String fileName = this.selectedListado;
            String tipo = this.selectedTipoArchivo;
            Object[] obj = (Object[]) this.selectedSeccion;
            Seccion tempSeccion = (Seccion) obj[0];
            String params = "&tipo=" + tipo + "&idSeccion=" + tempSeccion.getIdSeccion();
            this.url = this.url + fileName + params;
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Información:", "Debe seleccionar una sección"));
        }
    }

    /** Muestra los datos de la BD en la tabla*/
    public void populateSecciones() {
        this.secciones = new ArrayList();
        Session session = HibernateUtil.getSessionFactory().openSession();
        String sql = "SELECT s, g, n, a "
                + "FROM Seccion s JOIN s.grado g " /*Hala el grado y el nivel alque esta amarrado*/
                + "JOIN g.nivel n "
                + "JOIN s.anioescolar a "
                + "ORDER BY a.nuAnio DESC, n.nuNivel ASC, g.nuGrado ASC, s.vcSeccion ASC";
        Query query = session.createQuery(sql);
        this.secciones = (ArrayList) query.list();
        session.close();
    }

    /** Cargar Secciones en el formato Grado Seccion*/
    public ArrayList<SelectItem> cargarSecciones() {
        ArrayList<SelectItem> lista = new ArrayList<SelectItem>();
        StatelessSession session = HibernateUtil.getSessionFactory().openStatelessSession();
        String sql = "SELECT anioescolar.boEstado, "
                + "grado.vcNomGrado, "
                + "seccion.idSeccion, "
                + "seccion.vcSeccion, "
                + "nivel.nuNivel "
                + "FROM anioescolar INNER JOIN seccion ON anioescolar.idAnioEscolar = seccion.anioescolar_idAnioEscolar "
                + "INNER JOIN grado ON seccion.grado_idgrado = grado.idGrado "
                + "INNER JOIN nivel ON grado.nivel_idNivel = nivel.idNivel "
                + "WHERE anioescolar.boEstado = :valor "                
                + "ORDER BY nivel.nuNivel, grado.nuGrado , seccion.vcSeccion ASC ";
        Query hQuery = session.createSQLQuery(sql);
        hQuery.setParameter("valor", true);

        Iterator iter = hQuery.list().iterator();

        while (iter.hasNext()) {
            Object[] obj = (Object[]) iter.next();
            lista.add(new SelectItem(obj[2], obj[1] + " " + obj[3], ""));
        }
        session.close();
        return lista;
    }

    /** Mostrar los Niveles en el combo*/
    public ArrayList<SelectItem> cargarNiveles() {
        ArrayList<SelectItem> lista = new ArrayList<SelectItem>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Criteria cSeccion = session.createCriteria(Nivel.class);
        cSeccion.addOrder(Order.asc("nuNivel"));
        Iterator iter = cSeccion.list().iterator();

        while (iter.hasNext()) {
            Nivel s = (Nivel) iter.next();
            lista.add(new SelectItem(s.getIdNivel(), s.getVcNomNivel(), ""));
        }
        session.close();
        return lista;
    }

    public void onSelectNivel() {
        GradoBean n = (GradoBean) FacesUtil.getBean("gradoBean");
        this.listaGrados = n.cargarListaGrados(this.selectedNivel);
    }

    /** Getters & Setters */
    public Seccion getSeccion() {
        return seccion;
    }

    public void setSeccion(Seccion seccion) {
        this.seccion = seccion;
    }

    public Long getSelectedNivel() {
        return selectedNivel;
    }

    public void setSelectedNivel(Long selectedNivel) {
        this.selectedNivel = selectedNivel;
    }

    public Long getSelectedGrado() {
        return selectedGrado;
    }

    public void setSelectedGrado(Long selectedGrado) {
        this.selectedGrado = selectedGrado;
    }

    public ArrayList<SelectItem> getListaGrados() {
        return listaGrados;
    }

    public void setListaGrados(ArrayList<SelectItem> listaGrados) {
        this.listaGrados = listaGrados;
    }

    public ArrayList getSecciones() {
        return secciones;
    }

    public void setSecciones(ArrayList secciones) {
        this.secciones = secciones;
    }

    public Object[] getSelectedSeccion() {
        return selectedSeccion;
    }

    public void setSelectedSeccion(Object[] selectedSeccion) {
        this.selectedSeccion = selectedSeccion;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getSelectedListado() {
        return selectedListado;
    }

    public void setSelectedListado(String selectedListado) {
        this.selectedListado = selectedListado;
    }

    public String getSelectedTipoArchivo() {
        return selectedTipoArchivo;
    }

    public void setSelectedTipoArchivo(String selectedTipoArchivo) {
        this.selectedTipoArchivo = selectedTipoArchivo;
    }

    public Long getSelectedAnio() {
        return selectedAnio;
    }

    public void setSelectedAnio(Long selectedAnio) {
        this.selectedAnio = selectedAnio;
    }    
}